home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1999
/
MacHack 1999.toast
/
The Hacks
/
AltiVec Effect
/
EffectFilter16.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-03-13
|
4KB
|
101 lines
#include "BltMacros.h"
void EffectFilter16(BlitGlobals *glob);
void EffectFilter16(BlitGlobals *glob)
{
long height = glob->height; // Local copy of the height of the sources and destination
UInt16 *srcA = glob->sources[0].srcBaseAddr; // Local pointer to the first source image
UInt16 *srcB = glob->sources[1].srcBaseAddr; // Local pointer to the second source image
UInt16 *dst = glob->dstBaseAddr; // Local pointer to the destination
long srcABump;
long srcBBump;
long dstBump;
float dimMultiple;
// Work out the source and destination "bumps". The rowBytes value gives you the number
// of bytes in each scanline of an image. This is not necessarily the same as the number
// of pixels in a scanline multiplied by the number of bytes each pixel occupies. When
// we copy pixels from source to destination, via our effect algorithm, we need to
// account for this discrepancy. The following lines lines pre-calculate the differences.
srcABump = glob->sources[0].srcRowBytes - (glob->width * 2);
srcBBump = glob->sources[1].srcRowBytes - (glob->width * 2);
dstBump = glob->dstRowBytes - (glob->width * 2);
// Depending on the direction we are currently fading in (fading down the first source,
// or fading up the second) pre-calculate the percentage brightness of the pixels of the
// destination. The dimValue always has the percentage and is set in the Begin function.
if (glob->direction)
dimMultiple = 1.0 - (((float) glob->dimValue) / 255.0);
else
dimMultiple = (((float) glob->dimValue) / 255.0);
// Now, for every scanline in the source image we are dealing with...
while (height--)
{
long width = glob->width;
// ...iterate through every pixel in that scanline
while (width--)
{
UInt16 overlayPixel;
UInt16 preservedAlpha;
UInt16 newRed, newGreen, newBlue;
// Depending on the direction, take the next pixel of the first or the
// second source.
if (glob->direction)
{
// NOTE: You must not put the increment operator inside
// the Get16 macro, or you will end up incrementing srcA
// multiple times per pass.
overlayPixel = Get16(srcA);
srcA++;
}
else
{
overlayPixel = Get16(srcB);
srcB++;
}
// Call to BltMacros to ensure the pixel format is
// converted appropriately
cnv16SPFto16RG(overlayPixel);
// Dim all of the RGB values by the same amount, but leave the alpha
// channel value unchanged
preservedAlpha = 0x8000 & overlayPixel;
// The following lines extract the R, G and B channels of the source
// pixel, respectively. Each value is then multiplied by the pre-
// calculated dimMultiple, to produce the destination R, G and B
// channel values
newRed = ((overlayPixel & 0x7C00) >> 10) * dimMultiple;
newGreen = ((overlayPixel & 0x03E0) >> 5) * dimMultiple;
newBlue = ((overlayPixel & 0x001F) >> 0) * dimMultiple;
// Re-assemble the A, R, G and B values into a 16-bit destination pixel
overlayPixel = (preservedAlpha) | (newRed << 10) | (newGreen << 5) | (newBlue << 0);
// Set the destination pixel to be the dimmed version of the
// appropriate source pixel. The dimmed pixel value is first
// passed through the BltMacro to ensure the correct pixel
// format conversion is performed
cnv16RGto16DPF(overlayPixel);
Set16(dst,overlayPixel);
dst++;
}
// Bump the source and destination pointers we are using, to avoid
// problems when moving from one scanline to the next
if (glob->direction)
srcA = (void *)(((Ptr) srcA) + srcABump);
else
srcB = (void *)(((Ptr) srcB) + srcBBump);
dst = (void *)(((Ptr) dst) + dstBump);
}
// And we're done...
} // DrawEffectFrameEffect16Bit